package com.qiniu.pili.droid.rtcstreaming.demo.main;

import android.app.Activity;
import android.app.ProgressDialog;
import android.widget.Toast;

import com.qiniu.pili.droid.rtcstreaming.RTCConferenceOptions;
import com.qiniu.pili.droid.rtcstreaming.RTCStartConferenceCallback;
import com.qiniu.pili.droid.rtcstreaming.RTCStreamingManager;
import com.qiniu.pili.droid.rtcstreaming.demo.R;
import com.qiniu.pili.droid.rtcstreaming.demo.core.StreamUtils;
import com.qiniu.pili.droid.rtcstreaming.demo.test.AudioCapturer;
import com.qiniu.pili.droid.streaming.AVCodecType;
import com.qiniu.pili.droid.streaming.StreamingProfile;

import org.json.JSONException;
import org.json.JSONObject;

import java.net.URISyntaxException;

/**
 * Created by Leo on 2018/1/30.
 */

public class StreamingUtils {

    private static final String TAG = "Leo";
    private RTCStreamingManager mStreamingManager;
    private StreamingProfile mStreamingProfile;

    private AudioCapturer mAudioCapturer;
    private ProgressDialog mProgressDialog;
    private Activity mContext;

    private String publishUrl;
    private String roomToken;
    private String roomId;
    private String userId;
    private final SpeexUtil mSpeexUtil;

    public void setPublishUrl(String publishUrl) {
        this.publishUrl = publishUrl;
    }

    public void setRoomToken(String roomToken) {
        this.roomToken = roomToken;
    }

    public void setRoomId(String roomId) {
        this.roomId = roomId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }


    private static volatile StreamingUtils mStreamingUtils;

    private StreamingUtils() {
        mSpeexUtil = SpeexUtil.getInstance();
    }

    public static StreamingUtils getInstance() {
        synchronized (StreamingUtils.class) {

            if (mStreamingUtils == null) {
                synchronized (StreamingUtils.class) {
                    if (mStreamingUtils == null) {
                        mStreamingUtils = new StreamingUtils();
                    }
                }

            }
            return mStreamingUtils;
        }
    }

    /**
     * 初始化
     *
     * @author Leo
     * created at 2018/1/29 下午4:43
     */
    public void init(Activity context, int role) {
        //1.转成ARScanMainActivity
        mContext = context;
        //2.初始化推流的sdk
        RTCStreamingManager.init(context.getApplicationContext());
        //3.实例化推流manager
        mStreamingManager = new RTCStreamingManager(context, AVCodecType.SW_VIDEO_WITH_SW_AUDIO_CODEC);
        if (role == RecorderConstant.anchor) { //主播才设置推流参数
            //4.连麦参数设置
            RTCConferenceOptions options = new RTCConferenceOptions();
            options.setVideoEncodingSizeRatio(RTCConferenceOptions.VIDEO_ENCODING_SIZE_RATIO.RATIO_16_9);
            options.setVideoEncodingSizeLevel(RTCConferenceOptions.VIDEO_ENCODING_SIZE_HEIGHT_720);
            options.setVideoBitrateRange(300 * 1000, 800 * 1000);
            // 15 fps is enough
            options.setVideoEncodingFps(15);
            //5.主播端推流参数配置
            mStreamingProfile = new StreamingProfile();
            mStreamingProfile
                    .setVideoQuality(StreamingProfile.VIDEO_QUALITY_HIGH2)//视频流
                    .setAudioQuality(StreamingProfile.AUDIO_QUALITY_HIGH1)
                    .setEncoderRCMode(StreamingProfile.EncoderRCModes.QUALITY_PRIORITY)
                    .setEncodingOrientation(StreamingProfile.ENCODING_ORIENTATION.PORT)
                    .setPreferredVideoEncodingSize(RecorderConstant.width, RecorderConstant.height); // 配置推流的尺寸，建议与连麦尺寸一致

            mStreamingManager.setConferenceOptions(options);

            //6.prepare完成配置
            mStreamingManager.prepare(mStreamingProfile);
        }

        //7.初始化音频采集
        mAudioCapturer = new AudioCapturer();
        //提示dialog
        mProgressDialog = new ProgressDialog(context);
    }


    public boolean prepareInputStreaming() {
        if (publishUrl == null) {
            return false;
        }

        try {
            if (StreamUtils.IS_USING_STREAMING_JSON) {
                mStreamingProfile.setStream(new StreamingProfile.Stream(new JSONObject(publishUrl)));
            } else {
                mStreamingProfile.setPublishUrl(publishUrl);
            }
        } catch (JSONException e) {
            e.printStackTrace();
            return false;
        } catch (URISyntaxException e) {
            e.printStackTrace();
            return false;
        }

        mStreamingManager.setStreamingProfile(mStreamingProfile);
        if (!mStreamingManager.startStreaming()) {
            mStreamingManager.startStreaming();
            return false;
        }
        /**
         * Because `startPublishStreaming` need a long time in some weak network
         * So we should check if the activity paused.
         */

        if (mStreamingManager.isStreamingStarted()) {
            mContext.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    dismissDialog();
                    toastUtils("成功开启直播！");
                }
            });
        }
        return true;
    }


    public void inputAudioFrame() {
        startConference();
    }

    public void inputVideoFrame(byte[] bytes, int width, int height, int type, long ts) {

        mStreamingManager.inputVideoFrame(bytes, width, height, 0, false, type, ts);
        prepareInputStreaming();
    }


    public void onResume() {
        mStreamingManager.resume();
    }

    public void onPause() {
        mStreamingManager.pause();
    }


    /**
     * 停止推流
     *
     * @author Leo
     * created at 2018/1/29 下午3:54
     */
    public void stopPublishStreaming() {
        if (mStreamingManager.isStreamingStarted()) {
            mStreamingManager.stopStreaming();
        }
        toastUtils("结束直播");
    }

    /**
     * 停止连麦
     *
     * @author Leo
     * created at 2018/1/29 下午3:54
     */
    public void stopConference() {
        if (mAudioCapturer.isCaptureStarted()) {
            mAudioCapturer.setOnAudioFrameCapturedListener(null);
            mAudioCapturer.stopCapture();
        }
        mStreamingManager.stopConference();
        toastUtils("结束连麦");

    }

    public void onDestroy() {
        mStreamingManager.destroy();
        RTCStreamingManager.deinit();
    }


    /**
     * 加入连麦
     *
     * @author Leo
     * created at 2018/1/29 下午4:02
     */
    public void startConference() {
        //开始采集音频
        mAudioCapturer.startCapture();

        new Thread(new Runnable() {
            @Override
            public void run() {
                startConferenceInternal();
            }
        }).start();

    }

    private void startConferenceInternal() {
        if (roomToken == null) {
            toastUtils("无法获取房间信息 !");
        }

        if (roomToken != null && userId != null && roomId != null) {
            try {
                Thread.sleep(1000);
                mStreamingManager.startConference(userId, roomId, roomToken, new RTCStartConferenceCallback() {
                    @Override
                    public void onStartConferenceSuccess() {
                        if (mAudioCapturer.isCaptureStarted()) {
//
                            mAudioCapturer.setOnAudioFrameCapturedListener(new AudioCapturer.OnAudioFrameCapturedListener() {
                                @Override
                                public void onAudioFrameCaptured(byte[] audioData, long ts) {
                                    if (audioData != null) {
//                                        mSpeexUtil.encode(audioData,)
                                        mStreamingManager.inputAudioFrame(audioData, ts);
                                    } else {
                                        toastUtils("音频数据为空!");
                                    }
                                }
                            });
                        }

                        mContext.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                toastUtils("成功加入连麦！");
                                dismissDialog();
                            }
                        });

                    }

                    @Override
                    public void onStartConferenceFailed(final int errorCode) {


                        mContext.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                toastUtils(mContext.getString(R.string.failed_to_publish_av_to_rtc) + errorCode);
                                dismissDialog();
                            }
                        });
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            toastUtils("推流参数过期");
        }
    }

    private void toastUtils(String msg) {
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }


    public void showDialog(String msg) {
        mProgressDialog.setMessage(msg);
        mProgressDialog.show();
    }

    private void dismissDialog() {
        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

}
